package fr.lille.inria.adam.lifl.EcoGardeInventory.Activities;

import java.util.Arrays;

import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.util.SparseArray;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import fr.lille.inria.adam.lifl.EcoGardeInventory.R;
import fr.lille.inria.adam.lifl.EcoGardeInventory.Utils.EspeceEntry;
import fr.lille.inria.adam.lifl.EcoGardeInventory.Utils.SIGObservation;
import fr.lille.inria.adam.lifl.EcoGardeInventory.Utils.sparse.SparseAdapter;
import fr.lille.inria.adam.lifl.EcoGardeInventory.Utils.sparse.SparseEntry;
import fr.lille.inria.adam.lifl.EcoGardeInventory.Utils.sparse.SparseEntryValueCompareBuilder;

public class SelectStringEntryOnList extends BuildObservationActivity {
	public static final String extraIntentKey_STEP = "SELECTABLE_DATA_TYPE";
	protected ListView selectListView;
	
	private int etapeDeRealisation = -1;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		this.setContentView(R.layout.select_list);
		this.selectListView = (ListView) findViewById(R.id.selectListView);
	}
	
	@Override
	protected void onStart() {
		super.onStart();
		this.etapeDeRealisation = getIntent().getExtras().getInt(extraIntentKey_STEP, -1);
	}
	
	private void branchDataAtSelectList() {
		// Branche des donn�es � la ListView
		final SparseArray<String> rawData = retriveData();
		
		@SuppressWarnings("unchecked") //Java interdit l'invocation de SparseEntry<String>
		final SparseEntry<String>[] dataList = new SparseEntry[rawData.size()];
		SparseEntry.toArray(rawData, dataList, new SparseEntryValueCompareBuilder<String>());
		Arrays.sort(dataList);
		selectListView.setAdapter(new SparseAdapter(getApplicationContext(), R.layout.select_listitem, dataList));
		
		// Branchement du comportement onClick
		selectListView.setOnItemClickListener(new OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
				updateObservation(etapeDeRealisation, observationEnCoursDeRealisation, (int) id);
				
				// On change d'activit�
				Intent nextActivityIntent = getNextActivityIntent();
				startActivity(nextActivityIntent);
			}
		});
	}
	
	protected ServiceConnection initializeClientSIGServConn() {
		return new ServiceConnection() {
			
			@Override
			public void onServiceDisconnected(ComponentName name) {}
			
			@Override
			public void onServiceConnected(ComponentName name, IBinder service) {
				branchDataAtSelectList();
			}
		};
	}
	
	// Truc de generic
	public static final int TYPE_OBSERVATEUR = 0;
	public static final int TYPE_RECENSEMENT = 1;
	public static final int TYPE_GRPESPECE = 2;
	/**Renvoie le jeu de donn�e attendue par le type fourni.
	 * @param dataType SelectStringEntryOnList.TYPE_*
	 * @return
	 */
	private SparseArray<String> retriveData() {
		switch (etapeDeRealisation) {
		case TYPE_OBSERVATEUR: return this.clientBinder.retrieveObservateurs();
		case TYPE_RECENSEMENT: return this.clientBinder.retrieveRecensements();
		case TYPE_GRPESPECE: return this.clientBinder.retrieveGroupeEspeces();
		default: 
			Log.w(this.getClass().getSimpleName(), String.format("type inconnu retriveData(%d)", etapeDeRealisation));
			return new SparseArray<String>(0);
		}
	}
	
	
	/**M�thode qui renvoie l'Intent pour d�marrer la prochaine activit�.
	 * L'Intent contient:
	 *  - La classe de l'activit�
	 *  - l'observation en cours de r�alisation (SIG_OBSERVATION)
	 *  - si l'activit� suivante est SelectStringEntryOnListActivity 
	 *  alors l'�tape de r�alisation est pr�cis�e (SelectStringEntryOnListActivity.extraIntentKey_STEP)
	 * @return
	 */
	private Intent getNextActivityIntent() {
		Intent result = new Intent(getApplicationContext(), SelectStringEntryOnList.class);
		result.putExtra("SIG_OBSERVATION", observationEnCoursDeRealisation);
		result.putExtra("SIG_USER", user);

		switch (etapeDeRealisation) {
		case TYPE_OBSERVATEUR: 
			result.putExtra(extraIntentKey_STEP, TYPE_RECENSEMENT); break;
		case TYPE_RECENSEMENT:
			result.putExtra(extraIntentKey_STEP, TYPE_GRPESPECE); break;
		case TYPE_GRPESPECE:
			SparseArray<EspeceEntry> especes = clientBinder.retrieveEspeces(observationEnCoursDeRealisation.groupeEspece);
			result = new Intent(getApplicationContext(), (especes.size() > 0)
					?SelectEspece.class
					:QuantizePopulation.class);
			result.putExtra("SIG_OBSERVATION", observationEnCoursDeRealisation);
			result.putExtra("SIG_USER", user);
			break;
		default:
			Log.w(this.getClass().getSimpleName(), String.format("type inconnu getNextActivityIntent(%d)", etapeDeRealisation));
		}
		
		return result;
	}
	
	/**Met � jour l'observation (� l'aide de value) en fonction du 
	 * dataType de l'activit�
	 * @param dataType SelectStringEntryOnList.TYPE_*
	 * @param obs
	 * @param value
	 */
	private static void updateObservation(int dataType, SIGObservation obs, int value) {
		switch (dataType) {
		case TYPE_OBSERVATEUR: obs.observateur = value; break;
		case TYPE_RECENSEMENT: obs.recensement = value; break;
		case TYPE_GRPESPECE: obs.groupeEspece = value; break;
		default:
			Log.w(SelectStringEntryOnList.class.getSimpleName(), String.format("type inconnu updateObservation(%d)", dataType));
			break;
		}
	}
}
